/**
 * @file	httpUtil.c
 * @brief	HTTP Server Utilities	
 * @version 1.0
 * @date	2014/07/15
 * @par Revision
 *			2014/07/15 - 1.0 Release
 * @author	
 * \n\n @par Copyright (C) 1998 - 2014 WIZnet. All rights reserved.
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "httpUtil.h"
#include "W25Q64.h"


uint8_t http_get_cgi_handler(uint8_t * uri_name, uint8_t * buf, uint32_t * file_len)
{
	uint8_t ret = HTTP_OK;
	uint16_t len = 0;

	if(predefined_get_cgi_processor(uri_name, buf, &len))
	{
		;
	}
	else if(strcmp((const char *)uri_name, "get_netinfo.cgi") == 0)
	{
		// To do
		printf("Processing get_netinfo.cgi request.\r\n");

        // 假设有一些函数可以获取网络参数
        char ip[] = "192.168.1.100";
        char gateway[] = "192.168.1.1";
        char subnet[] = "255.255.255.0";
        char mac[] = "00:1A:2B:3C:4D:5E";
		    char dns[] = "114.114.114.114";
		
		

        //NetworkConfig configRead;  // 用于存储读取的内容
		
				//W25Q64_ReadData(0x080000, (uint8_t*)&configRead, sizeof(NetworkConfig));		//读取刚写入的测试数据到读取数据的测试数组中
		    

        // 生成JSON数据
//        len = sprintf((char *)buf,
//            "{ \"ip\": \"%s\", \"gw\": \"%s\", \"sn\": \"%s\", \"mac\": \"%s\", \"dns\": \"%s\" }",
//            configRead.ip, configRead.gateway, configRead.subnet, mac, dns
//        );
				len = sprintf((char *)buf,
            "{ \"ip\": \"%s\", \"gw\": \"%s\", \"sn\": \"%s\", \"mac\": \"%s\", \"dns\": \"%s\" }",
            ip, gateway, subnet, mac, dns
        );

        printf("Response Data: %s\r\n", buf);
		;
	}
	else if (strcmp((const char *)uri_name, "get_socketinfo.cgi") == 0)
  {
      printf("Processing get_socketinfo.cgi request.\r\n");     		
 
      // 构建 JSON 响应，注意所有 socket 共享一个 remote IP（server_ip）
      len = sprintf((char *)buf,
          "{"
          "\"sock0\": {\"local\": %d, \"rip\": \"%d.%d.%d.%d\", \"rport\": %d},"
          "\"sock1\": {\"local\": %d, \"rip\": \"%d.%d.%d.%d\", \"rport\": %d},"
          "\"sock2\": {\"local\": %d, \"rip\": \"%d.%d.%d.%d\", \"rport\": %d},"
          "\"sock3\": {\"local\": %d, \"rip\": \"%d.%d.%d.%d\", \"rport\": %d},"
          "\"sock4\": {\"local\": %d, \"rip\": \"%d.%d.%d.%d\", \"rport\": %d},"
          "\"sock5\": {\"local\": %d, \"rip\": \"%d.%d.%d.%d\", \"rport\": %d}"
          "}",
          // sock0
          socket_config.localport0,
          socket_config.server_ip[0], socket_config.server_ip[1],
          socket_config.server_ip[2], socket_config.server_ip[3],
          socket_config.port0,
          // sock1
          socket_config.localport1,
          socket_config.server_ip[0], socket_config.server_ip[1],
          socket_config.server_ip[2], socket_config.server_ip[3],
          socket_config.port1, 
          // sock2  
          socket_config.localport2,   
          socket_config.server_ip[0], socket_config.server_ip[1],
          socket_config.server_ip[2], socket_config.server_ip[3],
          socket_config.port2, 
          // sock3  
          socket_config.localport3,
          socket_config.server_ip[0], socket_config.server_ip[1],
          socket_config.server_ip[2], socket_config.server_ip[3],
          socket_config.port3, 
          // sock4   
          socket_config.localport4,
          socket_config.server_ip[0], socket_config.server_ip[1],
          socket_config.server_ip[2], socket_config.server_ip[3],
          socket_config.port4, 
          // sock5  
          socket_config.localport5,
          socket_config.server_ip[0], socket_config.server_ip[1],
          socket_config.server_ip[2], socket_config.server_ip[3],
          socket_config.port5
      );
		  
      //printf("SocketInfo JSON: %s\r\n", buf);
  }
	else
	{
		// CGI file not found
		ret = HTTP_FAILED;
	}

	if(ret)	*file_len = len;
	return ret;
}

uint8_t http_post_cgi_handler(uint8_t * uri_name, st_http_request * p_http_request, uint8_t * buf, uint32_t * file_len)
{
	uint8_t ret = HTTP_OK;
	uint16_t len = 0;
	uint8_t val = 0;

	if(predefined_set_cgi_processor(uri_name, p_http_request->URI, buf, &len))
	{
		;
	}
	else if(strcmp((const char *)uri_name, "example.cgi") == 0)
	{
		// To do
		val = 1;
		len = sprintf((char *)buf, "%d", val);
	}
	else
	{
		// CGI file not found
		ret = HTTP_FAILED;
	}

	if(ret)	*file_len = len;
	return ret;
}

uint8_t predefined_get_cgi_processor(uint8_t * uri_name, uint8_t * buf, uint16_t * len)
{
	uint8_t ret = 1;	// ret = 1 means 'uri_name' matched
	uint8_t cgibuf[14] = { 0, };
	int8_t cgi_dio = -1;
	int8_t cgi_ain = -1;

	uint8_t i;

	if (strcmp((const char*) uri_name, "get_netinfo.cgi") == 0) {
		make_json_netinfo(buf, len);
	}
    else if (strcmp((const char*) uri_name, "get_socketinfo.cgi") == 0) {
        make_json_socketinfo(buf, len); // 
    }	

	return ret;
	
	//;
}

uint8_t predefined_set_cgi_processor(uint8_t * uri_name, uint8_t * uri, uint8_t * buf, uint16_t * len)
{
	uint8_t ret = 1;	// ret = '1' means 'uri_name' matched
	uint8_t val = 0;
  // 打印收到的 CGI 请求
	printf("Received CGI request: %s\n", uri_name);
			
	if (strcmp((const char*) uri_name, "set_diostate.cgi") == 0) {
		//val = set_diostate(uri);
		*len = sprintf((char*) buf, "%d", val);
	}
	else if (strcmp((const char*) uri_name, "set_netinfo.cgi") == 0)
	{
   		//NetCfg_TypeDef configRead = NetworkConfig_Read();
   		//HAL_Delay(100); 
   		// 打印读取到的Config
   		//把传进来的ip赋给configRead
   		// uint8_t *param;
   		// uint8_t *ip = 0, *gw = 0, *sn = 0;
   		// if ((param = get_http_param_value((char*) uri, "ip")))
   		// 打印buf
   		printf("ip = %s\r\n", get_http_param_value((char*) uri, "ip"));
   		printf("gw = %s\r\n", get_http_param_value((char*) uri, "gw"));
   		printf("sn = %s\r\n", get_http_param_value((char*) uri, "sn"));
		  printf("dns = %s\r\n", get_http_param_value((char*) uri, "dns"));
		  printf("mac = %s\r\n", get_http_param_value((char*) uri, "mac"));
   		// 将 字符串 "192.168.0.99" 以"."分割 赋值给configRead.ip 数组
   	
   		// 把传进来的ip赋给configRead
   		uint8_t *ip_str = get_http_param_value((char*) uri, "ip");
   		if (ip_str != NULL) {
   			char *token;
   			int i = 0;
   			token = strtok((char *)ip_str, ".");
   			while (token != NULL && i < 4) {
   				localnet_config.auch_SIP[i] = (uint8_t)atoi(token);
   				token = strtok(NULL, ".");
   				i++;
   			}
   		}
   
   		// 把传进来的gw赋给configRead
   		uint8_t *gw_str = get_http_param_value((char*) uri, "gw");
   		if (gw_str!= NULL) {
   			char *token;
   			int i = 0;
   			token = strtok((char *)gw_str, ".");
   			while (token!= NULL && i < 4) {
   				localnet_config.auch_GA[i] = (uint8_t)atoi(token);
   				token = strtok(NULL, ".");
   				i++;
   			}
   		}
   
   		// 把传进来的sub赋给configRead
   		uint8_t *sn_str = get_http_param_value((char*) uri, "sn");
   		if (sn_str!= NULL) {
   			char *token;
   			int i = 0;
   			token = strtok((char *)sn_str, ".");
   			while (token!= NULL && i < 4) {
   				localnet_config.auch_SUB[i] = (uint8_t)atoi(token);
   				token = strtok(NULL, ".");
   				i++;				
   
   			}
   		}
			// 把传进来的dns赋给configRead
   		uint8_t *dns_str = get_http_param_value((char*) uri, "dns");
   		if (dns_str!= NULL) {
   			char *token;
   			int i = 0;
   			token = strtok((char *)dns_str, ".");
   			while (token!= NULL && i < 4) {
   				localnet_config.auch_DNS[i] = (uint8_t)atoi(token);
   				token = strtok(NULL, ".");
   				i++;  
   			}
   		}
			// 把传进来的 MAC 地址赋给 localnet_config
			uint8_t *mac_str = get_http_param_value((char*) uri, "mac");
			if (mac_str != NULL) {
					char *token;
					int i = 0;
					token = strtok((char *)mac_str, ":"); // MAC 地址以冒号分隔
					while (token != NULL && i < 6) {
							localnet_config.auch_SHA[i] = (uint8_t)strtol(token, NULL, 16); // 使用 strtol 将每部分转换为 16 进制的数字
							token = strtok(NULL, ":");
							i++;
					}
			}
			
			
   		NetworkConfig_Write(localnet_config);
   	
   		// 发送重启提示响应给客户端
   		uint16_t response_len;
   		const char* response = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: 18\r\n\r\nMCU will restart soon.";
   		response_len = strlen(response);
   		send(buf, &response_len); // 假设存在一个发送HTTP响应的函数
   
   		// 等待一段时间，确保响应发送完成
   		HAL_Delay(100); // 等待100ms，可根据实际情况调整
   
   		// 重启MCU
   		HAL_NVIC_SystemReset();
   	  //;
   }
	else if (strcmp((const char*) uri_name, "set_socketinfo.cgi") == 0)
	{  
		// s0_local=40000&s0_rip=192.168.1.100&s0_rport=40001&  	
    	// 把传进来的socket参数赋给socket_config
    	for (int i = 0; i < 6; i++) 
		{
    	    char key_local[20], key_rip[20], key_rport[20];
			
            //把格式化后的字符串写入 key_local 这个字符数组中
    	    sprintf(key_local, "s%d_local", i);            
    	    
    	    sprintf(key_rport, "s%d_rport", i);
            //printf("remoteportkey is sock%d and string is %s\n", i, key_rport);
            //printf(key_rip,   "s%d_rip", i);

            // 解析 localport
            // 解析本地端口 sX_local
            uint8_t *local_str = get_http_param_value((char*)uri, key_local);
            if (local_str != NULL) {
                uint16_t port = (uint16_t)atoi((char*)local_str);
                switch(i) {
                    case 0: socket_config.localport0 = port; break;
                    case 1: socket_config.localport1 = port; break;
                    case 2: socket_config.localport2 = port; break;
                    case 3: socket_config.localport3 = port; break;
                    case 4: socket_config.localport4 = port; break;
                    case 5: socket_config.localport5 = port; break;
                }
            }

            // 解析远程端口 sX_rport
    		uint8_t *rport_str = get_http_param_value((char*)uri, key_rport);
    		if (rport_str != NULL) {
    		    uint16_t port = (uint16_t)atoi((char*)rport_str);
    		    switch(i) {
    		        case 0: socket_config.port0 = port; break;
    		        case 1: socket_config.port1 = port; break;
    		        case 2: socket_config.port2 = port; break;
    		        case 3: socket_config.port3 = port; break;
    		        case 4: socket_config.port4 = port; break;
    		        case 5: socket_config.port5 = port; break;
    		    }
    		}
		}
		// 统一 server_ip：只取 s0_rip 来赋值
		uint8_t *rip_str = get_http_param_value((char*)uri, "s0_rip");
		if (rip_str != NULL) {
		    char rip_buf[20];
		    strncpy(rip_buf, (char*)rip_str, sizeof(rip_buf));
		    rip_buf[sizeof(rip_buf) - 1] = '\0';
		
		    char *token = strtok(rip_buf, ".");
		    int j = 0;
		    while (token != NULL && j < 4) {
		        socket_config.server_ip[j] = (uint8_t)atoi(token);
		        token = strtok(NULL, ".");
		        j++;
		    }
		}

		SocketConfig_Write(socket_config);
        
		// 发送重启提示响应给客户端
   		uint16_t response_len;
   		const char* response = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: 18\r\n\r\nMCU will restart soon.";
   		response_len = strlen(response);
   		send(buf, &response_len); 

        // 等待一段时间，确保响应发送完成
   		HAL_Delay(100); // 等待100ms，可根据实际情况调整
   
   		// 重启MCU
   		HAL_NVIC_SystemReset();

	} 
	return ret;
}


void make_json_netinfo(uint8_t *buf, uint16_t *len) 
{
	// wiz_NetInfo netinfo;
	// ctlnetwork(CN_GET_NETINFO, (void*) &netinfo);

	// DHCP: 1 - Static, 2 - DHCP
	*len =
			sprintf((char*) buf,
					"NetinfoCallback({\"mac\":\"%.2X:%.2X:%.2X:%.2X:%.2X:%.2X\",\
											\"ip\":\"%d.%d.%d.%d\",\
											\"gw\":\"%d.%d.%d.%d\",\
											\"sn\":\"%d.%d.%d.%d\",\
											\"dns\":\"%d.%d.%d.%d\",\
											\"dhcp\":\"%d\"\
											});",
					localnet_config.auch_SHA[0],localnet_config.auch_SHA[1], localnet_config.auch_SHA[2], 
			    localnet_config.auch_SHA[3],localnet_config.auch_SHA[4], localnet_config.auch_SHA[5],
					localnet_config.auch_SIP[0],localnet_config.auch_SIP[1], localnet_config.auch_SIP[2], localnet_config.auch_SIP[3],
					localnet_config.auch_GA[0], localnet_config.auch_GA[1],  localnet_config.auch_GA[2],  localnet_config.auch_GA[3],
					localnet_config.auch_SUB[0],localnet_config.auch_SUB[1], localnet_config.auch_SUB[2], localnet_config.auch_SUB[3],
					localnet_config.auch_DNS[0],localnet_config.auch_DNS[1], localnet_config.auch_DNS[2], localnet_config.auch_DNS[3],
					0x00
					);
}


void make_json_socketinfo(uint8_t *buf, uint16_t *len) 
{
  
      // 构建 JSON 响应，注意所有 socket 共享一个 remote IP（server_ip）
      *len = sprintf((char *)buf,
          "SocketInfoCallback({"
          "\"sock0\": {\"local\": %d, \"rip\": \"%d.%d.%d.%d\", \"rport\": %d},"
          "\"sock1\": {\"local\": %d, \"rip\": \"%d.%d.%d.%d\", \"rport\": %d},"
          "\"sock2\": {\"local\": %d, \"rip\": \"%d.%d.%d.%d\", \"rport\": %d},"
          "\"sock3\": {\"local\": %d, \"rip\": \"%d.%d.%d.%d\", \"rport\": %d},"
          "\"sock4\": {\"local\": %d, \"rip\": \"%d.%d.%d.%d\", \"rport\": %d},"
          "\"sock5\": {\"local\": %d, \"rip\": \"%d.%d.%d.%d\", \"rport\": %d}"
          "})",
          // sock0
          socket_config.localport0,
          socket_config.server_ip[0], socket_config.server_ip[1],
          socket_config.server_ip[2], socket_config.server_ip[3],
          socket_config.port0,
          // sock1
          socket_config.localport1,
          socket_config.server_ip[0], socket_config.server_ip[1],
          socket_config.server_ip[2], socket_config.server_ip[3],
          socket_config.port1, 
          // sock2  
          socket_config.localport2,   
          socket_config.server_ip[0], socket_config.server_ip[1],
          socket_config.server_ip[2], socket_config.server_ip[3],
          socket_config.port2, 
          // sock3  
          socket_config.localport3,
          socket_config.server_ip[0], socket_config.server_ip[1],
          socket_config.server_ip[2], socket_config.server_ip[3],
          socket_config.port3, 
          // sock4   
          socket_config.localport4,
          socket_config.server_ip[0], socket_config.server_ip[1],
          socket_config.server_ip[2], socket_config.server_ip[3],
          socket_config.port4, 
          // sock5  
          socket_config.localport5,
          socket_config.server_ip[0], socket_config.server_ip[1],
          socket_config.server_ip[2], socket_config.server_ip[3],
          socket_config.port5
      );
		  
      //printf("SocketInfo JSON: %s\r\n", buf);
}
